/*
 * Copyright (c) 2022, OUXIAOLONG. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.examples.springboot.jpa.domain;

import java.util.Iterator;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.Singular;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@EqualsAndHashCode

@Entity
@Table
public class Climber {
  @Id
//  @org.eclipse.persistence.annotations.UuidGenerator(name = "climber-id") // FIXME:Eclipselink use.
  @org.hibernate.annotations.GenericGenerator(name="climber-id", strategy = "uuid2")
  @GeneratedValue(generator = "climber-id")
  @Column(length=36)
  private String id;
  private String name;

  @Singular
//  @OneToMany // TODO: When using Hibernate, there is a conflict for foreign key unique constraint.
               // A better approach is: define @ManyToOne in many side.
  @ManyToMany
  @JoinTable(
      joinColumns = @JoinColumn(name = "Climber_id", referencedColumnName = "id"),
      inverseJoinColumns = @JoinColumn(name = "climbedMounts_id", referencedColumnName = "id", unique = false)
      )
  private Set<Mount> climbedMounts;

  @Singular
//  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) // TODO: When using Hibernate, there is a conflict for foreign key unique constraint.
               // A better approach is: define @ManyToOne in many side.
  @ManyToMany
  @JoinTable(
      joinColumns = @JoinColumn(name = "Climber_id", referencedColumnName = "id"),
      inverseJoinColumns = @JoinColumn(name = "phoneNumbers_id", referencedColumnName = "id", unique = false)
      )
  private Set<ClimberPhoneNumber> phoneNumbers;

  @Override
  public String toString() {
    Iterator<?> it;
    boolean hasNextElement = false;
    StringBuilder sb = new StringBuilder("{\"id\":\"").append(id);
    sb.append("\", \"name\":\"").append(name!=null?name:"").append('"');

    if(climbedMounts!=null) {
      sb.append(",\"climbedMounts\":[");
      it = climbedMounts.iterator();
      while (it.hasNext()) {
        if(hasNextElement)
          sb.append(',');
        sb.append(it.next().toString());
        hasNextElement=true;
      }
      sb.append(']');
    }

    hasNextElement = false;
    if (phoneNumbers != null) {
      sb.append(",\"phoneNumbers\":[");
      it = phoneNumbers.iterator();
      while (it.hasNext()) {
        if(hasNextElement)
          sb.append(',');
        sb.append(it.next().toString());
        hasNextElement=true;
      }
      sb.append('}');
    }

    return sb.append(']').toString();
  }

}
